package com.mocchira.music.radio;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.json.JSONObject;

import com.google.ads.AdRequest;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.database.DataSetObserver;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

public class FMRFavoriteActivity extends Activity {
    ExpandableListView list;
    FavoriteLists favList;
    MediaPlayerWrapper player;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.favorite);
        list = (ExpandableListView)findViewById(R.id.expandableListView);
        favList = new FavoriteLists(this);
        list.setAdapter(new FavoriteAdapter());
        player = new MediaPlayerWrapper();
        
        //AdRequest request = new AdRequest();
        //request.addTestDevice(AdRequest.TEST_EMULATOR);
        
    }

    @Override
    protected void onPause() {
        favList.finalize();
        super.onPause();
    }
    
    public class FavoriteAdapter implements ExpandableListAdapter, IDownloadListener {
        private List<View> mViewCache = new ArrayList<View>(favList.length());
        Map<String, Integer> url2viewIndex = new HashMap<String, Integer>();
        DownloadManager manager = new DownloadManager(FMRFavoriteActivity.this, this);
        
        public FavoriteAdapter() {
            for (int i = 0; i < favList.length(); i++) {
                mViewCache.add(null);
            }
        }
        
        @Override
        public boolean areAllItemsEnabled() {
            return true;
        }

        @Override
        public Object getChild(int groupPosition, int childPosition) {
            JSONObject obj = (JSONObject)getGroup(groupPosition);
            if (obj == null) return null;
            String ret = "";
            try {
                switch (childPosition) {
                case 0:
                    ret = obj.getString("artist_name");
                    break;
                case 1:
                    ret = obj.getString("album_name");
                    break;
                case 2:
                    ret = obj.getString("track_name");
                    break;
                case 3:
                    ret = obj.getString("track_lastfm_url");
                    break;
                case 4:
                    ret = obj.getString("logged_url");
                    break;
                default:
                    break;
                }
            } catch (Exception ex) {
                ret = "";
            }
            return ret;
        }

        @Override
        public long getChildId(int groupPosition, int childPosition) {
            return groupPosition * 100 + childPosition;
        }

        @Override
        public View getChildView(int groupPosition, int childPosition,
                boolean isLastChild, View convertView, ViewGroup parent) {
            try {
                switch (childPosition) {
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                    TextView textView;
                    if (convertView == null || convertView instanceof LinearLayout) {
                        textView = new TextView(FMRFavoriteActivity.this);
                        textView.setGravity(Gravity.LEFT);
                    } else {
                        textView = (TextView)convertView;
                    }
                    String ret = (String)getChild(groupPosition, childPosition);
                    textView.setText(ret);
                    return textView;
                case 5:
                    LinearLayout col = new LinearLayout(FMRFavoriteActivity.this);
                    col.setLayoutParams(new ExpandableListView.LayoutParams(ExpandableListView.LayoutParams.FILL_PARENT, ExpandableListView.LayoutParams.WRAP_CONTENT));
                    col.setOrientation(LinearLayout.HORIZONTAL);
                    col.setGravity(Gravity.LEFT);
                    Button playOrPauseButton;
                    playOrPauseButton = new Button(FMRFavoriteActivity.this);
                    playOrPauseButton.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
                    if (player.isPlaying(groupPosition))
                        playOrPauseButton.setText(R.string.pause);
                    else
                        playOrPauseButton.setText(R.string.play);
                    playOrPauseButton.setTag(new Integer(groupPosition));
                    playOrPauseButton.setOnClickListener(new ImageButton.OnClickListener(){
                        @Override
                        public void onClick(View v) {
                            int pos = (Integer)v.getTag();
                            if (player.isPlaying(pos)) {
                                player.pause();
                            } else {
                                player.start(pos);
                            }
                        }
                    });
                    col.addView(playOrPauseButton);
                    Button buttonBuyAlbum;
                    buttonBuyAlbum = new Button(FMRFavoriteActivity.this);
                    buttonBuyAlbum.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
                    buttonBuyAlbum.setText(R.string.buy_album);
                    buttonBuyAlbum.setTag(new Integer(groupPosition));
                    buttonBuyAlbum.setOnClickListener(new Button.OnClickListener(){
                        @Override
                        public void onClick(View v) {
                            int pos = (Integer)v.getTag();
                            JSONObject obj = (JSONObject)getGroup(pos);
                            try {
                                String artist = obj.getString("artist_name");
                                String album = obj.getString("album_name");
                                String url = AmazonAssociateUtil.getMusicLinkURL(Locale.getDefault(), artist, album);
                                Uri uri = Uri.parse(url);
                                Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                                startActivity(intent);
                            } catch (Exception ex) {};
                        }
                    });
                    col.addView(buttonBuyAlbum);
                    Button buttonBuyMP3;
                    buttonBuyMP3 = new Button(FMRFavoriteActivity.this);
                    buttonBuyMP3.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
                    buttonBuyMP3.setText(R.string.buy_mp3);
                    buttonBuyMP3.setTag(new Integer(groupPosition));
                    buttonBuyMP3.setOnClickListener(new Button.OnClickListener(){
                        @Override
                        public void onClick(View v) {
                            int pos = (Integer)v.getTag();
                            JSONObject obj = (JSONObject)getGroup(pos);
                            try {
                                String artist = obj.getString("artist_name");
                                String track = obj.getString("track_name");
                                String url = AmazonAssociateUtil.getMP3LinkURL(Locale.getDefault(), artist, track);
                                Uri uri = Uri.parse(url);
                                Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                                startActivity(intent);
                            } catch (Exception ex) {};
                        }
                    });
                    col.addView(buttonBuyMP3);
                    Button removeButton;
                    removeButton = new Button(FMRFavoriteActivity.this);
                    removeButton.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
                    removeButton.setText("Remove");
                    removeButton.setTag(new Integer(groupPosition));
                    removeButton.setOnClickListener(new Button.OnClickListener(){
                        @Override
                        public void onClick(View v) {
                            int pos = (Integer)v.getTag();
                            JSONObject obj = (JSONObject)getGroup(pos);
                            try {
                                favList.delete(obj);
                                mViewCache.remove(pos);
                                list.collapseGroup(pos);
                                list.invalidateViews();
                            } catch (Exception ex) {};
                        }
                    });
                    col.addView(removeButton);
                    return col;
                default:
                    ;
                }
            } catch (Exception ex) {
                ;
            }
            return null;
        }

        @Override
        public int getChildrenCount(int groupPosition) {
            return 6;
        }

        @Override
        public long getCombinedChildId(long groupId, long childId) {
            return childId;
        }

        @Override
        public long getCombinedGroupId(long groupId) {
            return groupId * 100;
        }

        @Override
        public Object getGroup(int groupPosition) {
            Iterator<String> ite = favList.iterator();
            int i = 0;
            String key = null;
            do {
                if (ite.hasNext())
                    key = ite.next();
                else
                    key = null;
            } while (i++ != groupPosition);
            if (key == null) return null;
            JSONObject obj = favList.get(key);
            return obj;
        }

        @Override
        public int getGroupCount() {
            return favList.length();
        }

        @Override
        public long getGroupId(int groupPosition) {
            return groupPosition;
        }

        @Override
        public View getGroupView(int groupPosition, boolean isExpanded,
                View convertView, ViewGroup parent) {
            View view = mViewCache.get(groupPosition);
            if (view != null) return view;
            LinearLayout col;
            ImageView imageView;
            TextView textView;
            JSONObject obj = (JSONObject)getGroup(groupPosition);
            String imgUrl = null;
            try {
                imgUrl = obj.getString("album_img_url");
                if (imgUrl == null || imgUrl.length() == 0) {
                    imgUrl = obj.getString("artist_img_url");
                }
                if (imgUrl != null && imgUrl.length() > 0) {
                    manager.enqueue(imgUrl);
                    url2viewIndex.put(imgUrl, new Integer(groupPosition));
                }
            } catch (Exception ex) {};
            col = new LinearLayout(FMRFavoriteActivity.this);
            col.setLayoutParams(new ExpandableListView.LayoutParams(ExpandableListView.LayoutParams.FILL_PARENT, ExpandableListView.LayoutParams.WRAP_CONTENT));
            col.setOrientation(LinearLayout.HORIZONTAL);
            col.setGravity(Gravity.LEFT);
            imageView = new ImageView(FMRFavoriteActivity.this);
            imageView.setLayoutParams(new LinearLayout.LayoutParams(80, 80));
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageView.setPadding(5, 5, 5, 5);
            imageView.setImageResource(R.drawable.loading);
            col.addView(imageView);
            textView = new TextView(FMRFavoriteActivity.this);
            textView.setGravity(Gravity.LEFT);
            col.addView(textView);
            try {
                textView.setText(obj.getString("track_name") + " by " + obj.getString("artist_name"));
            } catch (Exception ex) {};
            mViewCache.add(groupPosition, col);
            return col;
        }

        @Override
        public boolean hasStableIds() {
            return false;
        }

        @Override
        public boolean isChildSelectable(int groupPosition, int childPosition) {
            return false;
        }

        @Override
        public boolean isEmpty() {
            return favList.length() == 0;
        }

        @Override
        public void onGroupCollapsed(int groupPosition) {
            ;
        }

        @Override
        public void onGroupExpanded(int groupPosition) {
            ;
        }

        @Override
        public void registerDataSetObserver(DataSetObserver observer) {
        }

        @Override
        public void unregisterDataSetObserver(DataSetObserver observer) {
            observer.onChanged();
        }

        @Override
        public void onComplete(String url, File tmpFile, Exception ex) {
            if (ex != null) return;
            Bitmap bm = BitmapFactory.decodeFile(tmpFile.getAbsolutePath());
            tmpFile.delete();
            int index = url2viewIndex.get(url);
            LinearLayout col = (LinearLayout)mViewCache.get(index);
            ImageView imageview = (ImageView)col.getChildAt(0);
            imageview.setImageBitmap(bm);
        }

    }
    
    class MediaPlayerWrapper implements MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener, MediaPlayer.OnPreparedListener {
        private MediaPlayer player = new MediaPlayer();
        private int nowPlayingGID = -1;
        private JSONObject nowPlaying = null;
        ProgressDialog progress = null;
        
        public MediaPlayerWrapper() {
            super();
            player.setOnCompletionListener(this);
            player.setOnErrorListener(this);
            player.setOnPreparedListener(this);
            player.setAudioStreamType(AudioManager.STREAM_MUSIC);
        }
        public void finalize() {
            player.release();
        }
        
        private void prepareDownload(String flashHtml) {
            Pattern pattern = Pattern.compile("audio_file=([^&]+?)&");
            Matcher matcher = pattern.matcher(flashHtml);
            if (matcher.find()) {
                String url = matcher.group(1);
                url += "?plead=please-dont-download-this-or-our-lawyers-wont-let-us-host-audio";
                try {
                    prepare(url);
                } catch (Exception ex) {
                    Log.e(this.getClass().getName(), ex.getMessage(), ex);
                    try {progress.dismiss();}catch (Exception nex){};
                    Toast.makeText(FMRFavoriteActivity.this, "This resource might be unavailable", Toast.LENGTH_SHORT);
                    nowPlayingGID = -1;
                    list.invalidateViews();
                }
            }
        }
        private void prepare(String track) throws Exception {
            player.reset();
            player.setDataSource(track);
            player.prepareAsync();
        }
        @Override
        public void onPrepared(MediaPlayer mp) {
            try {progress.dismiss();}catch (Exception nex){};
            mp.start();
            list.invalidateViews();
        }
        @Override
        public boolean onError(MediaPlayer mp, int what, int extra) {
            try {progress.dismiss();}catch (Exception nex){};
            Toast.makeText(FMRFavoriteActivity.this, "This resource might be unavailable", Toast.LENGTH_LONG);
            nowPlayingGID = -1;
            list.invalidateViews();
            return true;
        }
        @Override
        public void onCompletion(MediaPlayer mp) {
            nowPlayingGID = -1;
            list.invalidateViews();
        } 
        public void start(int gid) {
            if (gid == nowPlayingGID) {
                player.start();
                list.invalidateViews();
                return;
            }
            nowPlayingGID = gid;
            if (nowPlaying != null) {
                if (player.isPlaying())
                    player.stop();
            }
            nowPlaying = (JSONObject)FMRFavoriteActivity.this.list.getExpandableListAdapter().getGroup(gid);
            list.invalidateViews();
            this.progress = ProgressDialog.show(FMRFavoriteActivity.this, "preparing...", "Download MP3 File");
            try {
                String html = nowPlaying.getString("player_html");
                prepareDownload(html);
            } catch (Exception ex) {
                Log.e(this.getClass().getName(), ex.getMessage(), ex);
            }
        }
        public void pause() {
            player.pause();
            list.invalidateViews();
        }
        public boolean isPlaying(int gid) {
            if (gid != nowPlayingGID) return false;
            return player.isPlaying();
        }
    }
    
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if(keyCode == KeyEvent.KEYCODE_BACK){
            player.finalize();
            finish();
            return super.onKeyDown(keyCode, event);
        }else{
            return false;
        }
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        menu.add(0, FMRTopActivity.MENU_BACK, 0, R.string.back);
        return true;
    }

    @Override
    public boolean onMenuItemSelected(int featureId, MenuItem item) {
        switch (item.getItemId()) {
        case FMRTopActivity.MENU_BACK:
            player.finalize();
            finish();
            break;
        }
        return super.onMenuItemSelected(featureId, item);
    }
    
}
